package com.cnhis.drgs.aspect;


import com.cnhis.drgs.annotation.Description;
import com.cnhis.drgs.util.DateUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

@Aspect
@Component
public class WebLogAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final int DEFAULT_LOST_TIME = 5;//默认5s

    /**
     * ()匹配没有参数；  (..)代表任意多个参数；   (*)代表一个参数，但可以是任意型；  (*,String)代表第一个参数为任何值,第二个为String类型
     * 1) execution(public * *(..))——表示匹配所有public方法
     * 2) execution(* set*(..))——表示所有以“set”开头的方法
     * 3) execution(* com.spring.springbootaop.service.AccountService.*(..))——表示匹配所有AccountService接口的方法
     * 4) execution(* com.spring.springbootaop.service.*.*(..))——表示匹配service包下所有的方法
     * 5) execution(* com.spring.springbootaop.service..*.*(..))——表示匹配service包和它的子包下的方法
     *
     * 切入指定注解
     *  @Pointcut("@annotation(org.spring.springboot.springbootaop.annotation.Description)")
     *
     *  切入指定包
     *  @Pointcut("execution(* org.spring.springboot.*.controller..*.*(..))")
     */




    @Pointcut("execution(* com.cnhis.grds.*.controller..*.*(..))")
    //切入点签名
    public void webLog() {
    }


    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        //开始执行时间
        long time = System.nanoTime();

        //目标方法签名
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

        //目标方法
        Method method = methodSignature.getMethod();

        //方法名
        String methodName = methodSignature.getName();

        //方法参数列表
        String[] parameterNames = methodSignature.getParameterNames();

        //参数值
        List<Object> args = Arrays.asList(joinPoint.getArgs());

        try {
            return joinPoint.proceed();

        } finally {
            BigDecimal lostTime = DateUtil.lostTime(time);

            //获取注解上的描述
            Description annotation = method.getAnnotation(Description.class);
            if (annotation != null) {
                methodName = annotation.value();
            }
            if (lostTime.compareTo(new BigDecimal(DEFAULT_LOST_TIME)) > 0) {
                logger.warn("【{}】执行耗时过久({})s，位置：{}，参数：{}", methodName, lostTime, methodSignature, args);
            }
//            else {
//                logger.info("【{}】执行耗时({})s，位置：{}，参数：{}", methodName, lostTime, methodSignature, args);
//            }
        }
    }




}
